#include "ServerThread.h"

ServerThread::ServerThread()
{	
	m_server = NULL;
	moveToThread(this);

	connect(this, SIGNAL(sigInit(int)), this, SLOT(onInit(int)));
	connect(this, SIGNAL(sigDeinit()), this, SLOT(onDeinit()));
	connect(this, SIGNAL(sigSendPack(int, NetPackPtr)), this, SLOT(onSendPack(int, NetPackPtr)));
	connect(this, SIGNAL(sigCloseConnect(int)), this, SLOT(onCloseConnect(int)));
}

ServerThread::~ServerThread()
{	
	Q_ASSERT(!m_server);
}

void ServerThread::init(int port)
{		
	emit sigInit(port);	
}

void ServerThread::deinit()
{
	emit sigDeinit();
	wait();
}

NetInfo ServerThread::netInfo(int netId)
{
    QMutexLocker lock(&m_mutex);
	Q_ASSERT(m_netInfo.contains(netId));
	return m_netInfo[netId];
}

void ServerThread::sendPack(int netId, const NetPackVariant &pack)
{
	QMutexLocker lock(&m_mutex);
	Q_ASSERT(m_netInfo.contains(netId));
	NetPackVariant *new_pack = new NetPackVariant(pack);
	emit sigSendPack(netId, NetPackPtr(new_pack));
}

void ServerThread::closeConnect(int netId)
{
	QMutexLocker lock(&m_mutex);
	Q_ASSERT(m_netInfo.contains(netId));
	emit sigCloseConnect(netId);
}

void ServerThread::onInit(int port)
{
	m_server = new NetServer(this);
	connect(m_server, SIGNAL(newConnect(int)), this, SLOT(onNewConnect(int)));
	connect(m_server, SIGNAL(disConnect(int)), this, SLOT(onDisConnect(int)));
	connect(m_server, SIGNAL(newDataRecv(int, NetPackPtr)), this, SIGNAL(newDataRecv(int, NetPackPtr)));

	m_server->startServer(port);
}

void ServerThread::onDeinit()
{
	m_server->stopServer();
	m_server->deleteLater();
	m_server = NULL;
	quit();	
}

void ServerThread::onNewConnect(int netid)
{
    QMutexLocker lock(&m_mutex);		
    m_netInfo[netid] = m_server->netInfo(netid);
    emit newConnect(netid);
}

void ServerThread::onDisConnect(int netid)
{
    QMutexLocker lock(&m_mutex);	
	m_netInfo.remove(netid);
    emit disConnect(netid);
}

void ServerThread::onSendPack(int netId, NetPackPtr pack)
{
	if (!m_netInfo.contains(netId))
		return;

	m_server->sendPack(netId, *pack);
}

void ServerThread::onCloseConnect(int netId)
{
	m_netInfo.remove(netId);
	m_server->closeConnect(netId);
}
